package org.ash.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.ash.base.constant.MessageConstant;
import org.ash.base.exception.AdBaseException;
import org.ash.base.ustils.RegexUtil;
import org.ash.base.ustils.ValidateCodeUtil;
import org.ash.user.mapper.UserMapper;
import org.ash.user.pojo.User;
import org.ash.user.pojo.dto.*;
import org.ash.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static org.ash.base.constant.MessageConstant.*;
import static org.ash.base.constant.RedisConstant.LOGIN_CODE_KEY;
import static org.ash.base.constant.RedisConstant.LOGIN_CODE_TTL;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public List<User> queryUsers(UserQueryDTO userQueryDTO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        // 构建查询条件
        if (userQueryDTO.getName() != null && !userQueryDTO.getName().isEmpty()) {
            queryWrapper.like("name", userQueryDTO.getName());
        }
        if (userQueryDTO.getSex() != null) {
            queryWrapper.eq("sex", userQueryDTO.getSex());
        }
        if (userQueryDTO.getPhone() != null && !userQueryDTO.getPhone().isEmpty()) {
            queryWrapper.eq("phone", userQueryDTO.getPhone());
        }
        if (userQueryDTO.getStatus() != null) {
            queryWrapper.eq("status", userQueryDTO.getStatus());
        }

        List<User> users = userMapper.selectList(queryWrapper);
        return users;
    }

    @Override
    public User addUser(UserUpdateDTO userUpdateDTO) {
        log.info("新增用户");

        // 检查用户名是否已存在
        Long count = count(new QueryWrapper<User>().eq("username", userUpdateDTO.getUsername()));
        if (count > 0) {
            AdBaseException.cast(USERNAME_HAS_EXISTED);
        }

        // 检查邮箱是否已存在
        count = count(new QueryWrapper<User>().eq("phone", userUpdateDTO.getPhone()));
        if (count > 0) {
            AdBaseException.cast(PHONE_HAS_EXISTED);
        }

        count = count(new QueryWrapper<User>().eq("email", userUpdateDTO.getEmail()));
        if (count > 0) {
            AdBaseException.cast(EMAIL_HAS_EXISTED);
        }

        // 创建 User 对象并填充必要字段
        User user = User.builder()
                .username(userUpdateDTO.getUsername())
                .password(userUpdateDTO.getPassword())
                .email(userUpdateDTO.getEmail())
                .phone(userUpdateDTO.getPhone())
                .name(userUpdateDTO.getName())
                .sex(userUpdateDTO.getSex())
                .dateOfBirth(userUpdateDTO.getDateOfBirth())
                .status(userUpdateDTO.getStatus())
                .role(userUpdateDTO.getRole())
                .address(userUpdateDTO.getAddress())
                .createTime(new Date()) // 设置当前时间
                .updateTime(new Date()) // 设置当前时间
                .createUser(1L)
                .updateUser(1L)
                .status(1) // 默认状态
                .build();
        boolean save = save(user);
        if (!save) {
            AdBaseException.cast("新增用户失败");
        }
        return user;
    }

    @Override
    public User updateById(Long id, UserUpdateDTO userUpdateDTO) {
        log.info("编辑用户");

        if (id == null || id <= 0) {
            AdBaseException.cast("用户 ID 无效");
        }
        if (getById(id) == null) {
            AdBaseException.cast(ACCOUNT_NOT_FOUND);
        }

        User user = getOne(new QueryWrapper<User>().eq("username", userUpdateDTO.getUsername()));
        if (user != null && user.getId() != id) {
            AdBaseException.cast(USERNAME_HAS_EXISTED);
        }
        user = getOne(new QueryWrapper<User>().eq("phone", userUpdateDTO.getPhone()));
        if (user != null && user.getId() != id) {
            AdBaseException.cast(PHONE_HAS_EXISTED);
        }
        user = getOne(new QueryWrapper<User>().eq("email", userUpdateDTO.getEmail()));
        if (user != null && user.getId() != id) {
            AdBaseException.cast(EMAIL_HAS_EXISTED);
        }

        User updatedUser = User.builder()
                .id(id) // 必须设置 ID，否则 MyBatis-Plus 不知道更新哪个用户
                .username(userUpdateDTO.getUsername())
                .password(userUpdateDTO.getPassword())
                .email(userUpdateDTO.getEmail())
                .phone(userUpdateDTO.getPhone())
                .name(userUpdateDTO.getName())
                .sex(userUpdateDTO.getSex())
                .dateOfBirth(userUpdateDTO.getDateOfBirth())
                .status(userUpdateDTO.getStatus())
                .role(userUpdateDTO.getRole())
                .address(userUpdateDTO.getAddress())
                .updateTime(new Date()) // 设置更新时间
                .build();

        boolean update = updateById(updatedUser);
        if (!update) {
            AdBaseException.cast("编辑用户失败");
        }
        return updatedUser;
    }

    @Override
    public User loginWithUsername(LoginFormDTO loginFormDTO) {
        log.info("登录请求");
        if (loginFormDTO == null) {
            log.info("用户请求为空");
        }
        log.info("username: {}", loginFormDTO.getUsername());
        log.info("password: {}", loginFormDTO.getPassword());

        // 处理用户登录逻辑，比如验证用户名和密码
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", loginFormDTO.getUsername());
        User user = getOne(queryWrapper);

        if (user == null) {
            AdBaseException.cast(ACCOUNT_NOT_FOUND);
        }
        if (!loginFormDTO.getPassword().equals(user.getPassword())) {
            AdBaseException.cast(PASSWORD_ERROR);
        }
        if (user.getStatus() == 0) {
            AdBaseException.cast(ACCOUNT_LOCKED);
        }
        return user;
    }

    @Override
    public User loginWithPhone(LoginPhoneFormDTO loginFormDTO) {
        String phone = loginFormDTO.getPhone();
        //从redis中获取验证码 校验验证码
        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
        String code = loginFormDTO.getCode();
        if (cacheCode == null || !cacheCode.equals(code)) {
            //不一致 报错
            AdBaseException.cast(MessageConstant.VERIFICATION_CODE_ERROR);
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        queryWrapper.eq("phone", phone);
        User user = userMapper.selectOne(queryWrapper);

        //判断用户是否存在
        if (user == null) {
            //不存在 创建新用户
            log.info("用户不存在，创建新用户");
            user = createUserWithPhone(phone);
        } else if (user.getStatus() == 0) {
            AdBaseException.cast(ACCOUNT_LOCKED);
        }

        return user;
    }

    @Override
    public User register(RegisterFormDTO registerFormDTO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", registerFormDTO.getUsername());
        if (userMapper.selectOne(queryWrapper) != null) {
            AdBaseException.cast(USERNAME_HAS_EXISTED);
        }

        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", registerFormDTO.getPhone());
        if (userMapper.selectOne(queryWrapper) != null) {
            AdBaseException.cast(PHONE_HAS_EXISTED);
        }

        // 保存用户信息
        User user = User
                .builder()
                .username(registerFormDTO.getUsername())
                .password(registerFormDTO.getPassword())
                .phone(registerFormDTO.getPhone())
                .status(1) // 默认正常
                .role(2)   // 默认普通用户
                .createTime(new Date())
                .updateTime(new Date())
                .build();

        int result = userMapper.insert(user);
        if (result <= 0) {
            return null;
        }
        return user;

    }

    private User createUserWithPhone(String phone) {
        User user = new User();
        user.setPhone(phone);
        //生成随机昵称
        user.setUsername(USER_NICK_NAME_PREFIX + ValidateCodeUtil.generateValidateCode4String(8));
        user.setPassword(USER_DEFAULT_PASSWORD);
        userMapper.insert(user);
        return user;
    }

    @Override
    public String sendCode(String phone) {
        //校验手机号
        if (RegexUtil.isPhoneInvalid(phone)) {
            //手机号不符合
            AdBaseException.cast(PHONE_FORMAT_INCORRECT);
        }
        //手机号符合,生成验证码
        String code = ValidateCodeUtil.generateValidateCode4String(6);

        //保存验证码到redis
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);

        log.info("发送验证码成功，验证码：{}", code);
        //返回ok
        return code;
    }
}
